/***************************************************************************************
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
*
* NEMU is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*          http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/

#include <common.h>
#include <elf.h>
extern uint64_t g_nr_guest_inst;
FILE *log_fp = NULL;
FILE *elf_fp = NULL;
Elf32_Shdr symbol_table_section;
Elf32_Shdr string_table_section;


void init_log(const char *log_file) {
  log_fp = stdout;
  if (log_file != NULL) {
    FILE *fp = fopen(log_file, "w");
    Assert(fp, "Can not open '%s'", log_file);
    log_fp = fp;
  }
  Log("Log is written to %s", log_file ? log_file : "stdout");
}

void init_elf(const char* elf_file){
  elf_fp = stdout;
  if (elf_fp != NULL){
    FILE *fp = fopen(elf_file, "r");
    if(fp == NULL){
      return ;
    }
    // Assert(fp, "Can not open '%s'", elf_file);
    elf_fp = fp;
    Elf32_Ehdr elf_header;
    size_t temp;
    temp = fread(&elf_header, sizeof(Elf32_Ehdr), 1, fp);
    if(memcmp(elf_header.e_ident, ELFMAG, SELFMAG) !=0 ){
      Log("Not a ELF file.");
      assert(0);
    }
    if(temp != 1){
      assert(0);
    }
    // Find the symbol table section
    fseek(fp, elf_header.e_shoff + elf_header.e_shentsize * (elf_header.e_shstrndx-2), SEEK_SET);
    temp = fread(&symbol_table_section, sizeof(Elf32_Shdr), 1, fp);
    if(temp != 1){
      assert(0);
    }
    
    // Find the string table section
    fseek(fp, elf_header.e_shoff + symbol_table_section.sh_link * elf_header.e_shentsize, SEEK_SET);
    temp = fread(&string_table_section, sizeof(Elf32_Shdr), 1, fp);
    if(temp != 1){
      assert(0);
    }

  }
  Log("Elf is read from %s", elf_file ? elf_file : "stdout");
}
bool log_enable() {
  return MUXDEF(CONFIG_TRACE, (g_nr_guest_inst >= CONFIG_TRACE_START) &&
         (g_nr_guest_inst <= CONFIG_TRACE_END), false);
}
